/*--------------------------------*- C++ -*----------------------------------*\
  =========                 |
  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
   \\    /   O peration     | Website:  https://openfoam.org
    \\  /    A nd           | Version:  dev
     \\/     M anipulation  |
\*---------------------------------------------------------------------------*/
FoamFile
{
    format      ascii;
    class       dictionary;
    object      testCalc;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //

a   1.1;
b   3.2;
c   #calc "$a*$b";

// Special care is required for calc entries that include a division since
// "/" is also used as the scoping operator to identify keywords in
// sub-dictionaries. For example, "$a/b" expects a keyword "b" within a
// sub-dictionary named "a". A division can be correctly executed by using a
// space between a variables and "/", e.g.

c   #calc "$a / $b";

// or bracketing the variable, e.g.

c   #calc "($a)/$b";

// Access to sub-entries using the "/" operator, e.g.
d
{
    b   4.8;
}
e   #calc "$a / $d/b";

// Access to higher-level sub-entries using the "../" operators, e.g.
f
{
    g #calc "$a / $../d/b";
}

s   "field";
fieldName #calc "$<string>s + \"Name\"";

time    100;
fileName #calc "\"movingBox_\" + name($time) + \".obj\"";

// Additional include files for the #calc code compilation can be specified
// using the #calcInclude entry, e.g. if functions from transform.H are used
angleOfAttack   5; // degs

angle           #calc "-degToRad($angleOfAttack)";

#calcInclude    "transform.H"
liftDir         #calc "transform(Ry($angle), vector(0, 0, 1))";
dragDir         #calc "transform(Ry($angle), vector(1, 0, 0))";

// Calculate the magnitude of the velocity and turbulent kinetic energy
// where the velocity is looked-up from testCalc2
magU            #calc "mag($<vector>testCalc2!U)";
k               #calc "1.5*magSqr(0.05*$<vector>{${FOAM_CASE}/testCalc2!U})";

// If the code string is delimited by '#{...#}' multiple lines and multiple
// code statements can be used to generate the entry  using 'os << ...;'.
// This is equivalent to #codeStream but with a more compact syntax.
#calcInclude    "transform.H"
maxAngle        30;
nAngles         7;
Us              #calc
#{
    const vector U($<vector>testCalc2!U);
    const int nAngles = $nAngles;
    const scalar angleStep = ($<scalar>maxAngle)/(nAngles - 1);
    List<vector> Us(nAngles);
    for(int i=0; i<nAngles; i++)
    {
        const scalar angle = degToRad(i*angleStep);
        Us[i] = transform(Ry(angle), U);
    }
    os << Us;
#};

// List of vectors example
listU           ((1.1 2.1 1.1) (2.1 3.2 4.1) (4.3 5.3 0));
magU1           #calc "mag($<List<vector>>listU[1])";

// Field of vectors and scalars example
#calcInclude    "Field.H"
magUs           #calc "mag($<Field<vector>>listU)";
magSqrU1        #calc "sqr($<Field<scalar>>magUs[1])";

#calcInclude    "HashTable.H"
namedU          (U0 (1.1 2.1 1.1) U1 (2.1 3.2 4.1) U2 (4.3 5.3 0));
magU2           #calc "mag($<HashTable<vector>>namedU[\"U2\"])";

// List of vectors stored as a typed compound example
listU2          List<vector> ((1.1 2.1 1.1) (2.1 3.2 4.1) (4.3 5.3 0));
magU21          #calc "mag($listU2[1])";

// ************************************************************************* //
